package service

import (
	"context"
	"fmt"
	"gitee.com/chicken-c/go-learn/webook/internal/repostiory"
	"gitee.com/chicken-c/go-learn/webook/internal/service/sms"
	"math/rand"
)

var (
	ErrCodeSendTooMany        = repostiory.ErrCodeSendTooMany
	ErrCodeVerifyTooManyTimes = repostiory.ErrCodeVerifyTooManyTimes
)

type CodeService interface {
	Send(ctx context.Context, biz string, phone string) error
	Verify(ctx context.Context, biz string, phone string, inputCode string) (bool, error)
}

type codeService struct {
	repo repostiory.CodeRepository
	sms  sms.Service
}

func NewcodeService(repo repostiory.CodeRepository, sms sms.Service) CodeService {
	return &codeService{
		repo: repo,
		sms:  sms,
	}
}

// 发送验证码
func (c *codeService) Send(ctx context.Context, biz string, phone string) error {
	//生成验证码
	code := c.generate()
	err := c.repo.Store(ctx, biz, phone, code)
	if err == repostiory.ErrCodeSendTooMany {
		return ErrCodeSendTooMany
	}
	if err != nil {
		return err
	}
	//模板ID
	var tqlId string = "SMS_473310227"
	//发送验证码
	err = c.sms.Send(ctx, tqlId, map[string]string{"code": code}, phone)
	return err
}

// 校验验证码
func (c *codeService) Verify(ctx context.Context, biz string, phone string, inputCode string) (bool, error) {
	ok, err := c.repo.Verify(ctx, biz, phone, inputCode)
	if err == repostiory.ErrCodeVerifyTooManyTimes {
		//这里需要接入告警
		//我们直接返回false了，给前端返回验证码错误的提示，屏蔽掉细节，防止试出来真的验证码
		return false, nil
	}
	return ok, err
}

func (c *codeService) generate() string {
	num := rand.Intn(999999)
	return fmt.Sprintf("%06d", num)
}
